/* Command.h
Michael Zahniser, 2008

Header file for the Command class, which is responsible for parsing a line of text to extract a command and arguments.
*/

#ifndef __GRINGOTTS_COMMAND_H__
#define __GRINGOTTS_COMMAND_H__

#include "Date.h"
#include "AccountType.h"

#include <string>
#include <vector>

using std::string;
using std::vector;



class Command {
public:
    enum Type {
	NONE,
	QUIT,
	BALANCE,
	CHECKS,
	INFO,
	RECORDS,
	TRANSACT,
	CANCEL,
	SET,
	CLEAR,
	TYPE,
	MAKE
    };


public:
    // Parse a line of text into a command.
    Command(const string &line);

    // Get the type of this command.
    Type GetType() const;
    // Get the date specified in this command, if any.
    const Date &GetDate() const;
    // Get the account name specified in this command, if any.
    const string &GetName() const;
    // Check if the name specified in this command matches the given name.
    bool MatchesName(const string &name) const;
    // Get any additional argument that was specified.
    const string &GetArgument() const;
    // Get the account types included by this command's filter.
    const vector<AccountType> &GetAccountTypes() const;


private:
    // Parser functions. Each one returns true if it successfully parsed
    // the line.
    bool ParseQuit(const string &line);
    bool ParseBalance(const string &line);
    bool ParseChecks(const string &line);
    bool ParseInfo(const string &line);
    bool ParseRecords(const string &line);
    bool ParseTransact(const string &line);
    bool ParseCancel(const string &line);
    bool ParseSetInfo(const string &line);
    bool ParseMake(const string &line);

    // Parse a line, loiking for a date specification.
    void ParseDate(string::const_iterator &it, const string &line);


public:
    static bool HasPrefix(const string &text, const string &prefix);
    static bool HasPrefix(string::const_iterator it, const string &prefix);
    static void NextToken(string::const_iterator &it, const string &line);
    static bool IsNumber(string::const_iterator it, const string &line);


private:
    Type type;
    Date date;
    string name;
    string argument;
    vector<AccountType> accountTypes;


private:
    static const string MONTH[];
};

#endif
